package ruc.InfluxDB.compress;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import okhttp3.Request;
import okhttp3.Response;
import ruc.Consts.constant;
import ruc.InfluxDB.InfluxDB_Common;

import java.io.IOException;
import ruc.InfluxDB.*;
import ruc.utils.IOUtils;

import java.util.HashMap;

class Info {
    float cpu_usage, memory_usage, disk_usage;
    public Info(float cpu_usage, float memory_usage, float disk_usage){
        this.cpu_usage = cpu_usage;
        this.memory_usage = memory_usage;
        this.disk_usage = disk_usage;
    }
}

public class InfluxDB_Accuracy {
    private String dbName, queryURL, tbName;
    public InfluxDB_Accuracy(String IP, String port, String dbName, String tbName) {
        String baseUrl = String.format("http://%s:%s", IP, port);
        this.queryURL = baseUrl + "/query?db=" + dbName;
        this.dbName = dbName;
        this.tbName = tbName;
    }

    public String convertAndSend(String eSql){
        String tmp = queryURL + "&q=" + eSql;
        Request request = new Request.Builder()
                .url(tmp)
                .build();

        try {
            Response res = InfluxDB_Common.getClient().newCall(request).execute();
            return res.body().string();
        }catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    private HashMap convert(String[] list) throws IOException {
        HashMap<String, Info> map = new HashMap();
        for(int k = 0; k < list.length; k++) {
            String[] v = list[k].split(constant.Delimiter);
            Info info = new Info(Float.parseFloat(v[4]), Float.parseFloat(v[5]), Float.parseFloat(v[6]));
            map.put(Long.parseLong(v[0]) + v[1] + v[2] + v[3], info);
        }
        return map;
    }

    private float loopBasicType(String str, HashMap<String, Info> map) {
        float res = 0;
        JSONArray jsonArray = JSONUtil.parseArray(str);
        for (int i = 0; i < jsonArray.size(); i++) {
            String ts = jsonArray.getJSONObject(i).getStr("timestamp");
            String ui = jsonArray.getJSONObject(i).getStr("userInfo");
            String hs = jsonArray.getJSONObject(i).getStr("hostname");
            String server = jsonArray.getJSONObject(i).getStr("server");
            String key = ts + ui + hs + server;
            String cup_usage = jsonArray.getJSONObject(i).getStr("cpu_usage");
            String memory_usage = jsonArray.getJSONObject(i).getStr("memory_usage");
            String disk_usage = jsonArray.getJSONObject(i).getStr("disk_usage");
            Info info = map.get(key);

            res += Math.pow(info.cpu_usage - Float.parseFloat(cup_usage), 2);
            res += Math.pow(info.disk_usage - Float.parseFloat(disk_usage), 2);
            res += Math.pow(info.memory_usage - Float.parseFloat(memory_usage), 2);
        }

        return res / jsonArray.size();
    }

    private float calAccuracy() throws IOException {
        String res = convertAndSend(String.format("select * from %s", tbName));
        if (res == "") {
            return 0;
        }
        HashMap map = convert(IOUtils.GetData());
        return loopBasicType(res, map);
    }
}
